package serialData;

import eightDataType.ByteUtil;
import utils.PrintUtil;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author Ajie
 * @date 2019-12-12
 * @function
 */
public class POSData {
    /**
     * 起始字符	包序号	命令类别	命令码	数据域长度	返回码	数据域	校验
     * 0x5A(1字节)
     * 0x00~0xFFFF(2字节)
     * 0x01(1字节)
     * (1字节)	高位在前
     *  (2字节)
     * (1字节)
     * (N字节)	LRC
     * (1字节)
     */

    public static void addFF() {
        Integer[] buffer = new Integer[] { 12, 36, 48, 56, 67, 89, 24 };
//        Integer[] buffer = new Integer[] { 12};
        int needSize = 3;
        Object[] sie = new Object[needSize];
        int leng = needSize;
        int bufLen = buffer.length;
        Object[] newSie = new Object[needSize];

        for (int currInd = 0; currInd >= 0;) {
            List<Integer> integers = Arrays.asList(buffer);
            sie = Arrays.asList(buffer).subList(currInd, leng).toArray();
            System.out.println("origin size "+integers.size()+" sub "+currInd+" -> "+leng+"  res:"+sie.length);
            if (sie.length == needSize) {
                System.out.println(Arrays.asList(sie));
            }
            currInd = leng;
            if (bufLen - leng - needSize > 0) {
                leng = leng + needSize;
            } else {
                leng = bufLen;
            }
            if (needSize > sie.length) {
                // 这里是复制数组、 你可以在这里进行一下优化。
                for (int i = 0; i < sie.length; i++) {
                    newSie[i] = sie[i];
                }
                // 补全
                for (int i = sie.length; i < needSize; i++) {
                    newSie[i] = 0xff;
                }
                break;
            }
        }
        System.out.println(Arrays.asList(newSie));
        return;
    }

    public static void main(String[] args) {

//        test();
//        addFF();
//        System.out.println("--------");
//        byte[] bytes = "0xFF".getBytes();
//        for (int i = 0; i < bytes.length; i++) {
//            System.out.println(" --- "+bytes[i]);
//        }
//
//        System.out.println(0xff);
//        System.out.println(Byte.MAX_VALUE);
        byte[] bytes = writeData("123456");
        PrintUtil.print(bytes);
    }

    private static void test() {
        byte[] a = new byte[1];
        byte minValue = Byte.MIN_VALUE;

        byte ff = 0;
        try {
            ff = ByteUtil.hexToByte("FF");
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        System.out.println(ff);
        String binaryStrFromByte = ByteUtil.getBinaryStrFromByte(ff);
        System.out.println("byte -->str "+binaryStrFromByte);


        int b = a[0] & 0xFF;
    }

    static volatile short packageNum = 0;
    static final int dataLen = 20;

    static boolean isDebug = false;
    private static byte[] writeData(String idNum) {
        if (idNum == null || idNum.length()==0){
            System.err.println("idnum null:"+idNum);
            return null;
        }
        List<Byte> bytesBuffer = new ArrayList<>();
        byte head =0x5A;
        byte b = -1;
        try {
            b = ByteUtil.hexToByte("5A");
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        System.out.println(b);
        //0x5A(1字节) head
        bytesBuffer.add(head);

        //包序号 0x00~0xFFFF (2字节)
        if (packageNum< Short.MAX_VALUE){
             packageNum++;
        }else {
            packageNum = 0;
        }
        byte[] bytesPk = ByteUtil.shortToBytes(packageNum);
        if (bytesPk.length!=2){
            throw new RuntimeException("short to bytes error short:"+packageNum);
        }
        bytesBuffer.add(bytesPk[0]);
        bytesBuffer.add(bytesPk[1]);
        if (isDebug){
            System.out.println("package ruank: "+bytesPk[0]+" "+bytesPk[1]);
//            PrintUtil.print(bytesPk);
//            System.out.println("byte-->short "+ByteUtil.bytesToShort(bytesPk));
        }

        //命令类别 0x01 (1字节)
        byte cmdType = 0x01;
        bytesBuffer.add(cmdType);

        //命令码 (1字节)	高位在前
        byte cmd = (byte) 0xA5;
        bytesBuffer.add(cmd);
        if (isDebug){
            System.out.println("byte-->hex:"+ByteUtil.byteToHex(cmd));
            System.out.println("cmd "+cmd);
        }

        //数据域长度 (2字节) 高位在前 todo 定长20
        byte[] dataLenBy = new byte[2];
        dataLenBy[0]=dataLen;
        bytesBuffer.add(dataLenBy[1]);
        bytesBuffer.add(dataLenBy[0]);
//        System.out.println("--->"+ByteUtil.bytesToShort(dataLen));

        //数据域 (N字节)todo 学工号20字节, ASC, 不够20字节, 左补FF
        byte[] idNumBytes = idNum.getBytes();
        if (idNumBytes.length>dataLen){
            throw new RuntimeException("idNumBytes > data length "+idNum+"  length:"+idNumBytes.length);
        }

        System.out.println();
        for (int i = 0; i < dataLen-idNumBytes.length; i++) {
            byte a = -1;
            bytesBuffer.add(a);
        }
        for (int i = dataLen-idNumBytes.length; i < dataLen; i++) {
            bytesBuffer.add(idNumBytes[i - (dataLen-idNumBytes.length) ]);
        }
        // 校验，这里采用BCC校验，为除起始字符外其他数据的异或值。  (1字节)
        bytesBuffer.add(getXor(bytesBuffer));


        byte[] bytes = new byte[bytesBuffer.size()];
        for (int i = 0; i < bytesBuffer.size(); i++) {
            bytes[i] = bytesBuffer.get(i);
        }
        return bytes;

//        包序号，从0开始，每发送一个数据包就加1，加到0xFFFF后
    }

    //异或校验
//    public static byte getXor(byte[] datas){
    public static byte getXor(List<Byte> datas){

        byte temp=datas.get(1);

        for (int i = 2; i <datas.size(); i++) {
            temp ^=datas.get(i);
        }

        return temp;
    }


}
